package com.hk.common.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

/**
 * @author miaoj
 */
public class JsonUtils {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static <T> T deserializeJson(String jsonObj, TypeReference<T> valueTypeRef) {

        if (jsonObj == null) {
            return null;
        }
        String metadata = jsonObj.trim();
        if (metadata.isEmpty()) {
            return null;
        }
        try {
            return (T) objectMapper.readValue(metadata, valueTypeRef);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T deserializeJson(InputStream inputStream, TypeReference<T> valueTypeRef) {
        if (inputStream == null) {
            return null;
        }
        try {
            return (T) objectMapper.readValue(inputStream, valueTypeRef);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T deserializeJson(String jsonObj, Class<T> cls) {
        if (jsonObj == null) {
            return null;
        }
        String metadata = jsonObj.trim();
        if (metadata.isEmpty()) {
            return null;
        }
        try {
            return (T) objectMapper.readValue(metadata, cls);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T deserializeJson(InputStream inputStream, Class<T> cls) {
        if (inputStream == null) {
            return null;
        }
        try {
            return (T) objectMapper.readValue(inputStream, cls);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T deserializeJson(String jsonObj) {
        if (jsonObj == null) {
            return null;
        }
        String metadata = jsonObj.trim();
        if (metadata.isEmpty()) {
            return null;
        }
        try {
            if (metadata.charAt(0) == '{') {
                return (T) objectMapper.readValue(metadata, Map.class);
            } else {
                return (T) objectMapper.readValue(metadata, List.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String serializeObject(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }

    }

    public static void serializeObject(OutputStream out, Object obj) {
        if (obj != null) {
            try {
                objectMapper.writeValue(out, obj);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    public static byte[] serializeObjectAsBytes(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsBytes(obj);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}
